home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / ArrangeScript / Sources / ArrangeScript.cp < prev    next >
Text File  |  1996-06-21  |  5KB  |  205 lines

  1. /*
  2.     This file defines a "generic" plugin module for Arrange 2.0.
  3.     To use it, you should modify the file 'SubClass.h', which subclasses
  4.     the Plugin class definition by adding new fields and private functions,
  5.     and implementing the appropriate methods in this C++ source file.
  6. */
  7.  
  8. #include "ArrangeScript.h"
  9.  
  10. #ifndef __APPLEEVENTS__
  11. #include <AppleEvents.h>
  12. #endif
  13.  
  14. #ifndef __AEREGISTRY__
  15. #include <AERegistry.h>
  16. #endif
  17.  
  18. #ifndef __COMPONENTS__
  19. #include <Components.h>
  20. #endif
  21.  
  22. #ifndef __OSA__
  23. #include <OSA.h>
  24. #endif
  25.  
  26. // Function prototypes
  27. static pascal OSErr HandlerGlue(AppleEvent* message, AppleEvent* reply, long    refCon);
  28.  
  29. /*************************************************************************/
  30. /**************************** GenericPlugin ******************************/
  31. /*************************************************************************/
  32.  
  33. ArrangeScript::ArrangeScript (const ArrangeCallbackTbl* theCalls) : 
  34.     Plugin (theCalls),
  35.     fWildCardHandler(NULL)
  36. {
  37.     // Add an item to the About Plugins menu for this plugin.
  38.     calls->ui->AddMenuItem(mPluginAbout, aboutMenuText, 0, aboutCmdCode, 0);
  39.     calls->ui->SetMenuItem(mPluginAbout, aboutCmdCode, 0, NULL, true, 0, 0);
  40.     
  41.     InstallMenuHook(0, true, aboutCmdCode);
  42.     
  43.     // Add a new scripting menu
  44.     // calls->ui->AddMenu(mScriptingText, mScripting, 0);
  45.     calls->ui->AddMenuItem(mTools, mExecuteMenuText, 0, mExecuteCmdCode, 0);
  46.     
  47.     InstallMenuHook(0, true, mExecuteCmdCode);
  48.     
  49.     // InstallEventHandlers();
  50. }
  51.  
  52. arHookResult ArrangeScript::MenuEvent(Integer commandCode,
  53.                                         Integer commandParam,
  54.                                         pShort modifiers)
  55. {
  56.     arHookResult result;
  57.     
  58.     switch (commandCode)
  59.     {
  60.         case aboutCmdCode:
  61.             Alert(qModuleRsrcID, NULL);
  62.             result = true;
  63.             break;
  64.             
  65.         case mExecuteCmdCode:
  66.             {
  67.                 Integer        selStart;
  68.                 Integer        selEnd;
  69.                 Integer        selResult;
  70.                 
  71.                     // get text size
  72.                 selResult = calls->sel->GetSelText(0, NULL, &selStart, &selEnd);
  73.                 if ((selResult > 0) && (selEnd > selStart))
  74.                 {
  75.                     long    bufferSize = selEnd + 1;
  76.  
  77.                     Handle buffer = (Handle)AllocMem(bufferSize, amHdl);
  78.                     if (buffer)
  79.                     {
  80.                         HLock(buffer);
  81.                         selResult = calls->sel->GetSelText(bufferSize, *buffer, &selStart, &selEnd);
  82.                         
  83.                         AEDesc scriptDesc;
  84.                         scriptDesc.descriptorType = typeNull;
  85.                         scriptDesc.dataHandle = NULL;
  86.                         
  87.                         AECreateDesc(typeChar, *(buffer + selStart), selEnd - selStart, &scriptDesc);
  88.                         
  89.                         DeallocMem(buffer, amHdl);
  90.                         
  91.                         ExecuteText(scriptDesc);
  92.                         
  93.                         AEDisposeDesc(&scriptDesc);
  94.                     }
  95.                 }
  96.                 else
  97.                 {
  98.                     StopAlert("Cannot execute. No text is selected.");
  99.                 }
  100.                 result = true;
  101.             }
  102.             break;
  103.             
  104.         default:
  105.             result = false;
  106.     }
  107.  
  108.     return result;
  109. }
  110.  
  111. ArrangeScript::~ArrangeScript ()
  112. {
  113.     if (fWildCardHandler)
  114.     {
  115.         AERemoveEventHandler(typeWildCard, typeWildCard, fWildCardHandler, false);
  116.         DisposeRoutineDescriptor(fWildCardHandler);
  117.         fWildCardHandler = NULL;
  118.     }
  119. }
  120.  
  121. void ArrangeScript::InstallEventHandlers()
  122. {
  123.     fWildCardHandler = NewAEEventHandlerProc(HandlerGlue);
  124.     if (fWildCardHandler)
  125.         AEInstallEventHandler(typeWildCard, typeWildCard, fWildCardHandler, (long)this, false);
  126. }
  127.  
  128. void ArrangeScript::ExecuteText(AEDesc& desc)
  129. {
  130.     ComponentInstance defaultComponent = 
  131.         OpenDefaultComponent(kOSAComponentType, kOSAGenericScriptingComponentSubtype);
  132.     OSAID newScriptID = kOSANullScript;
  133.     OSAID resultID = kOSANullScript;
  134.     OSAError osaErr;
  135.     AEDesc resultText;
  136.     resultText.descriptorType = typeNull;
  137.     resultText.dataHandle = NULL;
  138.     //osaErr = OSACompileExecute(defaultComponent, &desc, kOSANullScript, kOSAModeCanInteract, &resultID);
  139.     osaErr = OSADoScript(defaultComponent, &desc, kOSANullScript, typeChar, kOSAModeCanInteract, &resultText);
  140.     if (osaErr != noErr)
  141.     {
  142.         if (resultText.dataHandle && resultText.descriptorType == typeChar)
  143.         {
  144.             long startSize = GetHandleSize(resultText.dataHandle);
  145.             SetHandleSize(resultText.dataHandle, startSize + 1);
  146.             HLock(resultText.dataHandle);
  147.             *((*resultText.dataHandle) + startSize) = 0;
  148.             StopAlert((char*)**resultText.dataHandle);
  149.             HUnlock(resultText.dataHandle);
  150.         }
  151.         else
  152.             StopAlert("An error occurred compiling and executing the script.");
  153.     }
  154.     
  155.     AEDisposeDesc(&resultText);
  156.     
  157.     CloseComponent(defaultComponent);
  158. }
  159.  
  160. arDocumentPtr ArrangeScript::MakeFrontDocCurrent()
  161. {
  162.         // fast and loose...assumes at least one doc is open
  163.     arDocumentPtr oldDoc = calls->doc->GetCurrentDoc();
  164.     calls->doc->SetCurrentDoc(GetIndexedDoc(0));
  165.     return oldDoc;
  166. }
  167.  
  168. void ArrangeScript::DoCreateElementEvent(AppleEvent* message, AppleEvent* reply)
  169. {
  170.     arDocumentPtr oldDoc = MakeFrontDocCurrent();
  171.     
  172.     arTypeID builtInType = calls->sysObj->GetBuiltInObject(boNoteDefType);
  173.     arNoteID newNote = CreateNote(arNoteType, true);
  174.     
  175.     arTopicID curTopic = calls->sysObj->GetCurrentTopic(calls->sel->GetActiveWindow(), true);
  176.     calls->data->AddListFieldEntry(curTopic, 0, 0, newNote, nullSFF);
  177.     
  178.     calls->doc->SetCurrentDoc(oldDoc);
  179. }
  180.  
  181. static pascal OSErr HandlerGlue(AppleEvent* message,
  182.                         AppleEvent* reply,
  183.                         long    refCon)
  184. {
  185.     OSErr         result;
  186.     AEKeyword     eventID;
  187.     AEKeyword     actualType;
  188.     long        actualSize;
  189.     
  190.     ArrangeScript* plugin = (ArrangeScript*)refCon;
  191.  
  192.     
  193.     AEGetAttributePtr(message, keyEventIDAttr, typeType, &actualType, &eventID, sizeof(AEKeyword), &actualSize); 
  194.     switch (eventID)
  195.     {
  196.         case kAECreateElement:
  197.             plugin->DoCreateElementEvent(message, reply);
  198.             result = noErr;
  199.             break;
  200.             
  201.         default:
  202.             result = errAEEventNotHandled;
  203.     }
  204.     return result;
  205. }